home *** CD-ROM | disk | FTP | other *** search
- /*
- * The functions in this file maintain a hash table of strings and manage
- * string buffers.
- */
- #include "../h/gsupport.h"
-
- /*
- * Prototype for static function.
- */
- hidden int streq Params((int len,char *s1,char *s2));
-
- struct str_entry {
- char *s;
- int length;
- struct str_entry *next;
- };
-
- #define SBufSize 1024
- #define StrTblSz 149
- static struct str_entry *str_tbl[StrTblSz];
-
- /*
- * init_str - initialize string hash table.
- */
- novalue init_str()
- {
- static int first_time = 1;
- int h;
-
- if (first_time)
- first_time = 0;
- else
- return;
-
- for (h = 0; h < StrTblSz; ++h)
- str_tbl[h] = NULL;
- }
-
- /*
- * init_sbuf - initialize a new sbuf struct, allocating an initial buffer.
- */
- novalue init_sbuf(sbuf)
- struct str_buf *sbuf;
- {
- sbuf->size = SBufSize;
- sbuf->strtimage = (char *)alloc((unsigned)SBufSize);
- sbuf->endimage = sbuf->strtimage;
- sbuf->end = sbuf->strtimage + SBufSize;
- }
-
- /*
- * new_sbuf - allocate a new buffer for a sbuf struct, copying the partially
- * created string from the full buffer to the new one.
- */
- novalue new_sbuf(sbuf)
- struct str_buf *sbuf;
- {
- char *s1, *s2;
-
- #if IntBits == 16
- unsigned int oldsize = sbuf->size;
- sbuf->size += (sbuf->size/2);
- if (sbuf->size < oldsize) { /* check for overflow */
- sbuf->size = MaxBlock;
- }
- #else /* IntBits == 16 */
- sbuf->size *= 2;
- #endif /* IntBits == 16 */
- s1 = sbuf->strtimage;
- sbuf->strtimage = (char *)alloc((unsigned)sbuf->size);
- s2 = sbuf->strtimage;
- while (s1 < sbuf->endimage)
- *s2++ = *s1++;
- sbuf->endimage = s2;
- sbuf->end = sbuf->strtimage + sbuf->size;
- }
-
- /*
- * spec_str - install a special string in the string table.
- */
- char *spec_str(s)
- char *s;
- {
- struct str_entry *se;
- register char *s1;
- register int l;
- register int h;
-
- h = 0;
- l = 1;
- for (s1 = s; *s1 != '\0'; ++s1) {
- h += *s1 & 0377;
- ++l;
- }
- h %= StrTblSz;
- for (se = str_tbl[h]; se != NULL; se = se->next)
- if (l == se->length && streq(l, s, se->s))
- return se->s;
- se = NewStruct(str_entry);
- se->s = s;
- se->length = l;
- se->next = str_tbl[h];
- str_tbl[h] = se;
- return s;
- }
-
- /*
- * str_install - find out if the string in the buffer is in the string table.
- * If not, put it there. Return a pointer to the string in the table.
- */
- char *str_install(sbuf)
- struct str_buf *sbuf;
- {
- int h;
- struct str_entry *se;
- register char *s;
- register char *e;
- int l;
-
- AppChar(*sbuf, '\0')
- s = sbuf->strtimage;
- e = sbuf->endimage;
- h = 0;
- while (s < e)
- h += *s++ & 0377;
- h %= StrTblSz;
- s = sbuf->strtimage;
- l = e - s;
- for (se = str_tbl[h]; se != NULL; se = se->next)
- if (l == se->length && streq(l, s, se->s)) {
- sbuf->endimage = s;
- return se->s;
- }
- se = NewStruct(str_entry);
- se->s = s;
- se->length = l;
- sbuf->strtimage = e;
- se->next = str_tbl[h];
- str_tbl[h] = se;
- return se->s;
- }
-
- /*
- * streq - compare s1 with s2 for len bytes, and return 1 for equal,
- * 0 for not equal.
- */
- static int streq(len, s1, s2)
- register int len;
- register char *s1, *s2;
- {
- while (len--)
- if (*s1++ != *s2++)
- return 0;
- return 1;
- }
-